<template>
  <div
    class="zui-selector"
    :class="{ multiple, disabled, readonly, row: direction == 'row', column: direction == 'column' }"
  >
    <div class="options">
      <div
        v-for="(option, idx) in options"
        class="option"
        :class="{ active: selectedOptionIndex.includes(idx), disabled, readonly }"
        :key="idx"
        @click="onOptionClick(idx)"
      >
        <i class="icon iconfont-zui" :class="[getOptionIconClass(idx)]"></i>
        <span class="label">{{ option.label }}</span>
        <zui-input
          v-if="option.editable"
          class="zui-input"
          v-model="option.addition"
          @click.stop="onInputClick(idx)"
          :disabled="!selectedOptionIndex.includes(idx)"
          @blur="emitUpdateModelValueEvent"
          placeholder="请填写"
          round
        />
      </div>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import ZuiInput from '../input/ZuiInput.vue'

const emit = defineEmits(['update:modelValue'])
const props = defineProps({
  multiple: Boolean,
  modelValue: {
    type: Array,
    default: () => []
  },
  options: {
    type: Array as () => Array<any>,
    default: function () {
      return [
        { label: '选项1', value: '选项值2' },
        { label: '选项2', value: '选项值1' }
      ]
    }
  },
  // row、column
  direction: {
    type: String,
    default: 'row'
  },
  disabled: Boolean,
  readonly: Boolean
})

//***** 已选 *****/
const selectedOptionIndex = ref()
const displayText = computed(() => {
  return props.modelValue
    .map((option: any) => {
      return option.addition ? `${option.label}(${option.addition})` : option.label
    })
    .join('/')
})

watch(
  () => props.modelValue,
  (val: any) => {
    // 初始化modelValue
    if (!val) {
      if (!props.options) {
        return
      }
      selectedOptionIndex.value = props.options.filter((option) => option.checked).map((option, idx) => idx)
      emitUpdateModelValueEvent()
    } else {
      // 挑出匹配的选项
      selectedOptionIndex.value = val
        .map((selectedVal: any) => {
          return props.options.findIndex((item: any) => {
            if (typeof selectedVal === 'string') {
              return item.value === selectedVal
            } else {
              return item.value === selectedVal.value
            }
          })
        })
        .filter((idx: Number) => idx > -1)
    }
  },
  { immediate: true }
)

function emitUpdateModelValueEvent() {
  if (!selectedOptionIndex.value) {
    return
  }
  const values = selectedOptionIndex.value.sort().map((idx: any) => {
    return props.options[idx]
  })

  emit('update:modelValue', values)
}

// 切换多选单选时需要清空已选
watch(
  () => props.multiple,
  (val) => {
    if (!val) {
      selectedOptionIndex.value.length = 0
    }
  }
)

function getOptionIconClass(idx: Number) {
  if (!props.multiple) {
    if (selectedOptionIndex.value.includes(idx)) {
      return 'icon-zui-radio-selected'
    }
    return 'icon-zui-radio-unselected'
  } else {
    if (selectedOptionIndex.value.includes(idx)) {
      return 'icon-zui-checkbox-checked'
    }
    return 'icon-zui-checkbox-unchecked'
  }
}

//***** 选择 *****/
function onOptionClick(idx: Number) {
  if (props.readonly || props.disabled) {
    return
  }
  toggleOption(idx, false)
  emitUpdateModelValueEvent()
}

function toggleOption(idx: Number, onlyCheck: Boolean) {
  if (props.multiple) {
    console.log('当前 idx', idx)
    if (selectedOptionIndex.value.includes(idx)) {
      if (!onlyCheck) {
        const target = selectedOptionIndex.value.findIndex((i: Number) => idx == i)
        selectedOptionIndex.value.splice(target, 1)
      }
    } else {
      selectedOptionIndex.value.push(idx)
    }
  } else {
    if (selectedOptionIndex.value.includes(idx)) {
      if (!onlyCheck) {
        selectedOptionIndex.value.length = 0
      }
    } else {
      selectedOptionIndex.value.length = 0
      selectedOptionIndex.value.push(idx)
    }
  }
}

function onInputClick(idx: Number) {
  toggleOption(idx, true)
}
</script>

<style lang="scss" scoped>
.zui-selector {
  width: 100%;
  text-align: left;
  background: #ffffff;
  position: relative;
  &.disabled {
    opacity: 0.5;
  }
  &.readonly {
    line-height: var(--zui-size-line-height-regular);
    padding: 6px 12px;
    box-sizing: border-box;
    border-radius: var(--zui-size-border-radius-small);
    background-color: var(--zui-color-fill-light);
    .icon {
      opacity: 0.5;
    }
  }
  .options {
    display: flex;
    flex-wrap: wrap;
    margin-left: -16px;

    .option {
      display: flex;
      align-items: flex-start;
      box-sizing: border-box;
      line-height: 32px;
      margin-left: 16px;
      .icon {
        display: inline-block;
        width: 16px;
        height: 16px;
        line-height: 32px;
        font-size: 19px;
        color: var(--zui-color-text-secondary);
      }

      .label {
        margin-left: 8px;
        line-height: 32px;
        min-height: 32px;
      }
      .zui-input {
        display: inline-block;
        margin-left: 8px;
      }
      &.active {
        color: var(--zui-color-primary);
        .icon {
          color: var(--zui-color-primary);
        }
      }
      &.readonly {
        &.active {
          color: var(--color-text-primary);
          .icon {
            color: var(--zui-color-text-primary);
          }
        }
      }
      &:not(.disabled):active {
        background: rgba($color: #f0f0f0, $alpha: 0.49);
      }
    }
  }
  &.column {
    .options {
      flex-direction: column;
    }
  }
}
</style>
